//
// Created by Ryan on 2020/11/28.
//

#include "common.h"
#include "string.h"
#include "elf.h"

// 如果是结构体本身的属性, 使用"."如果是结构体指针要指向结构体的属性, 使用"->"
// 从 multiboot_t 结构获取信息ELF
inline elf_m elf_from_multiboot(multiboot_m *mb)
{
    elf_m elf;
    elf_section_header_m *sh = (elf_section_header_m *)mb->addr;
    uint32_v shstrtab = sh[mb->shndx].addr;

    for (int i = 0; i < mb->num; i++)
    {
        const char *name = (const char *)(shstrtab + sh[i].name);
        if (!strcmp(name, ".strtab"))
        {
            elf.strtab = (const char *)sh[i].addr;
            elf.strtabsz = sh[i].size;
        }
        if (!strcmp(name, ".symtab"))
        {
            elf.symtab = (elf_symbol_m *)sh[i].addr;
            elf.symtabsz = sh[i].size;
        }
    }

    return elf;
}

// 查看ELF的符号信息
inline const char *elf_lookup_symbol(uint32_v addr, elf_m *elf)
{
    int i;

    for (i = 0; i < (elf->symtabsz / sizeof(elf_symbol_m)); i++)
    {
        if (ELF32_ST_TYPE(elf->symtab[i].info) != 0x2)
        {
            continue;
        }
        // 通过函数调用地址查到函数的名字(地址在该函数的代码段地址区间之内)
        if ((addr >= elf->symtab[i].value) && (addr < (elf->symtab[i].value + elf->symtab[i].size)))
        {
            return (const char *)((uint32_v)elf->strtab + elf->symtab[i].name);
        }
    }

    return NULL;
}
